﻿// JScript File
/// <reference path="_namespace.js" />
/// <reference path="../components/AjaxContainer.js" />
/// <reference path="WinFormDisplayFlags.js" />

/*****************************************************************************
Ajax library class definition. Kevin Robinson 2006.
Class: ajax.windows.WinForm
/*****************************************************************************/

ajax.lang.addNamespace("ajax.windows");
ajax.lang.imports("ajax.windows.WinFormDisplayFlags");

//-----------------------------------------------------------------------------
ajax.windows.WinForm = function(doc, sLayerName, w, h, displayFlags, sText, parentNode, bModal, taskBar) // Constructor
{///<field name="displayFlags" type="ajax.windows.WinFormDisplayFlags"/>
    w = w || 640;
    h = h || 480;
    
    ajax.windows.WinForm.superConstructor.call(this, doc, parentNode, sLayerName, w, h);       
    
	// Properties			
	this.minWidth           = 150;
	this.minHeight          = h;
	
	this.text               = (typeof(sText) != "undefined") ? sText : "Ajaxna Application";
	this.displayFlags       = (typeof(displayFlags) != "undefined") ? displayFlags : ajax.windows.WinFormDisplayFlags.None;
	this.modal              = (typeof(bModal) != "undefined") ? bModal : false;
	this.taskBar            = (typeof(taskBar) != "undefined") ? taskBar : null;
	      
	this.parentWinForm      = null; // Used if this WinForm is an MDI Child window
    
    // We will support some public events that clients can subscribe to, so set those up here.
    this.getEvent(this.window, "onFocus");
    this.getEvent(this.window, "onMinimise");
    this.getEvent(this.window, "onMaximise");
    this.getEvent(this.window, "onRestore");   
    this.getEvent(this.window, "onResizingStart");
    this.getEvent(this.window, "onResizingEnd"); 
    
        
    this.dialogArguments    = null; // Comms in
    this.returnValue        = null; // Comms out    
    this.menuBar            = null;
    this.menuContainer      = null;
	this.modalLayer         = null;
	this.transBack          = null;
	this.backFrame          = null;
	this.topLayer           = null;
	this.layer				= null;
	this.frame              = null;
	this.title              = null;
    this.canvas             = null;
    this.innerCanvas        = null;
    this.content            = null;
    this.status             = null;
    this.statusText         = null;
    this.titleShadow        = null;
    this.titleText          = null;
    this.minimiseButton     = null;
    this.maximiseButton     = null;
    this.closeButton        = null;
    this.resizeButton       = null;
    this.statusText         = null;
    this.icon               = null;
	this.layerOffsetX		= 0;
	this.layerOffsetY		= 0;
	this.tag				= null;
	this.templateFile       = ajax.getDomainPath() + "/windows/WinFormTemplate.html";
	this.iconFile           = ajax.getDomainPath() + "/images/dotnet.gif";
	this.controlBoxFile     = ajax.getDomainPath() + "/images/controlBox.gif";
	this.titleLeftImage     = ajax.getDomainPath() + "/images/TitleLeft.gif";
	this.titleRightImage    = ajax.getDomainPath() + "/images/TitleRight.gif";
	this.titleMiddleImage   = ajax.getDomainPath() + "/images/TitleMiddle.gif";
	this.resizeFile         = ajax.getDomainPath() + "/images/resize.gif";
	this.blankImageFile     = ajax.getDomainPath() + "/images/trans.gif";
	this.mdiTitleBackground = ajax.getDomainPath() + "/images/mdi_background.gif";
	// This will sync load the template immediately, and if not already in cache,
	// will cause some delay for the constructor to return.
	this.windowTemplateHtml = this.resourceCache.getFile(this.templateFile);
		
	// MDI objects
	this.mdiTitle           = null;      
    this.mdiTitleText       = null;    
    this.mdiMinimiseButton  = null;    
    this.mdiMaximiseButton  = null;    
    this.mdiCloseButton     = null;    
	
	
	// Define Styles here so they cannot be overridden, only appended to
	this.layerStyle = 
	{
	    position        : "absolute",
	    left            : "0px",
	    top             : "0px",
	    fontFamily      : "Arial",
	    fontSize        : "12px",
	    color           : "#000000",
	    cursor          : "default",
	    visibility      : "hidden"
	};
	this.titleStyle = 
	{
	    fontWeight      : "bold",
	    height          : "23px",
	    onselectstart   : null
	};
	
	this.canvasStyle = 
	{
	    width           : "100%",
	    backgroundColor : "#0033FF"	    
	};
	this.innerCanvasStyle = 
	{
	    position        : "absolute",
	    left            : "2px"	    
	};
	this.contentStyle   = 
	{
	    overflow        : "auto",
	    color           : "#000000",
	    backgroundColor : "ButtonFace"
	};
	this.statusStyle    = 
	{
	    height          : "16px",
	    backgroundColor : "ButtonFace",
	    color           : "#000000",
	    borderTop       : "solid 1px #FFFFFF",
	    onselectstart   : null   
	};
	this.modalScreenStyle = 
	{	    	    	    
	    position        : "absolute",
	    width           : "100%",
	    height          : "100%",
	    top             : "0px",
	    left            : "0px",
	    zIndex          : 10000	   
	};	
	this.transBackStyle = 
	{
	    position        : "absolute",
	    width           : "100%",
	    height          : "100%",
	    top             : "0px",
	    left            : "0px",
	    backgroundImage : "url(" + ajax.getDomainPath() + "/images/halfTrans.png)",
	    filter          : "Alpha(Opacity=50)"	    
	};
	this.hiddenFrameStyling = 
	{
	    marginHeight    : 0,
        marginWidth     : 0,
        frameBorder     : 0,
        unselectable    : "on",
        style           :
        {
            width           : "100%",
            Height          : "100%",
            position        : "absolute",
            top             : "0px",
            left            : "0px"
        }
	}
	this.minimiseButtonStyle = 
	{
	    backgroundImage     : "url(" + ajax.getDomainPath() + "/images/ControlBox.gif)",
	    backgroundPosition  : "0px 0px"	   
	};	
	this.maximiseButtonStyle = 
	{
	    backgroundImage     : "url(" + ajax.getDomainPath() + "/images/ControlBox.gif)",
	    backgroundPosition  : "-14px 0px"
	};	
	
	this.closeButtonStyle = 
	{
	    backgroundImage     : "url(" + ajax.getDomainPath() + "/images/ControlBox.gif)",
	    backgroundPosition  : "-28px 0px"
	};
	
	
	//-----------------------------------------------------------------------------
	// Some event handlers
	var self = this;
	
	// Called from this.layer
	this.bringToFront                   = function()
	{
		if (!this.layer)
			return;
			
	    if (self.parentNode.childNodes[self.parentNode.childNodes.length-1] != self.topLayer)
        {                  
            // Arrrg!! Due to an obscure IE bug we must save the states of all
            // Radio buttons and checkboxes on the page, before we move stuff about..
            var states = ajax.lang.safeNew("ajax.lang.SaveCheckStates", this.doc);
            states.save();                         
            
            // Items saved, now do the move
            self.parentNode.appendChild(self.topLayer);            
            
            // restore checks to original state
            states.restore();                          
                
            // Fire onFocus event
            self.onFocus.call(this);                            
        }
	}
	//-----------------------------------------------------------------------------
	this.onResizeStart                  = function(e)
	{	    	    
	    self.onResizingStart.call(self, self.getRect());
	    self.tempResizeButton                   = self.doc.createElement("img");
	    self.tempResizeButton.src               = self.resizeButton.src;
	    self.tempResizeButton.style.position    = "relative";
	    self.tempResizeButton.style.left        = "0px";
	    self.tempResizeButton.style.top         = "0px"; 
	    self.tempResizeButton.style.cursor      = self.resizeButton.style.cursor; 
	    self.resizeButton.style.display         = "none";
	    self.resizeButton.parentNode.appendChild(self.tempResizeButton);
	}
	//-----------------------------------------------------------------------------
	this.onResizeHandler                = function(e)
	{
	    // Get the position of the parent in relation to the entire document body	    
	    var elePos  = self.getElementPosition(self.parentNode, self.doc.body);
	    var offLeft = elePos.x;
	    var offTop  = elePos.y;
	        
	    // Work out what we want the size to be based on current size and how much the mouse moved
	    var newW = Math.max(self.width + e.x, self.minWidth);
	    var newH = Math.max(self.height + e.y, self.minHeight);
	
	    // Change the size if required
	    if (newW >= self.minWidth && newH >= self.minHeight)	    
	        self.setSize(newW, newH);
	        
	    // Reset the lastMousePosition of the DragController, so we only get movement
	    this.lastMouseX = parseInt(self.layer.style.left) + self.width + e.x + offLeft;
	    this.lastMouseY = parseInt(self.layer.style.top) + self.height + e.y + offTop;
	}
	//-----------------------------------------------------------------------------
	this.onResizeEnd                    = function(e)
	{
	    self.resizeButton.style.top         = "0px";
	    self.resizeButton.style.left        = "0px";
	    self.tempResizeButton.parentNode.removeChild(self.tempResizeButton);
	    self.resizeButton.style.display     = "block";
	    self.onResizingEnd.call(self, self.getRect());
	    
	}
	//-----------------------------------------------------------------------------
	this.controlBoxMouseOverHandler     = function() 
	{
	    // We do this because FF does not support backgroundPositionX & Y
	    var arrSplit = this.style.backgroundPosition.split(/ /);	
	    this.style.backgroundPosition  = arrSplit[0] +  " -14px"; 
	}
	//-----------------------------------------------------------------------------
	this.controlBoxMouseDownHandler     = function() 
	{  
	    var arrSplit = this.style.backgroundPosition.split(/ /);
	    this.style.backgroundPosition  = arrSplit[0] + " -28px"; 
	}
	//-----------------------------------------------------------------------------
	this.controlBoxMouseOutHandler      = function() 
	{  
	    var arrSplit = this.style.backgroundPosition.split(/ /);
	    this.style.backgroundPosition  = arrSplit[0] + " 0px";   
	}
	//-----------------------------------------------------------------------------
	this.onMinimiseHandler              = function(e)
	{
        self.minimise.call(self, e, this);
	}
	//-----------------------------------------------------------------------------
	this.onMaximiseHandler              = function(e)
	{	 	
        self.maximise.call(self, e, this);
	}
	//-----------------------------------------------------------------------------
	this.onRestoreHandler               = function(e)
	{	    	    	    	    
        self.restore.call(self, e, this);    	    
	}	
	//-----------------------------------------------------------------------------
	this.onCloseButtonHandler                 = function(e)
	{
        self.close.call(self, e, this);        
	}         	
	
	this.setSizeToContainerHandler              = function(e)
	{
	    // We are carefull here to only resize the form if required
	    // to avoid endless loops (we resize..causing the parent to resize...causing us to resize...)
	    var containerSize = self.getDomNodeSize(self.parentNode);
	    if (self.width != containerSize.width)
	        self.setSizeToContainerWidth.call(self);
	    if (self.height != containerSize.height)
	        self.setSizeToContainerHeight.call(self);	        	    	    
	}	
}

//-----------------------------------------------------------------------------
ajax.lang.extend("ajax.windows.WinForm", "ajax.components.AjaxContainer"); // Inherits
if ($getDesignMode())
    ajax.windows.WinForm.prototype = ajax.components.AjaxContainer.prototype;

// New code for start and end resize events.
ajax.windows.WinForm.prototype.displayFlags = ajax.windows.WinFormDisplayFlags.None;
ajax.windows.WinForm.prototype.add_resizingStart = function(handler) { this.getEvent(this.getWindow(), "onResizingStart").addListener(handler); }
ajax.windows.WinForm.prototype.remove_resizingStart = function(handler) { this.getEvent(this.getWindow(), "onResizingStart").removeListener(handler); }
ajax.windows.WinForm.prototype.add_resizingEnd = function(handler) { this.getEvent(this.getWindow(), "onResizingEnd").addListener(handler); }
ajax.windows.WinForm.prototype.remove_resizingEnd = function(handler) { this.getEvent(this.getWindow(), "onResizingEnd").removeListener(handler); }

ajax.windows.WinForm.prototype.add_minimise = function(handler) { this.getEvent(this.getWindow(), "onMinimise").addListener(handler); }
ajax.windows.WinForm.prototype.add_maximise = function(handler) { this.getEvent(this.getWindow(), "onMaximise").addListener(handler); }
ajax.windows.WinForm.prototype.add_restore = function(handler) { this.getEvent(this.getWindow(), "onRestore").addListener(handler); }
ajax.windows.WinForm.prototype.remove_minimise = function(handler) { this.getEvent(this.getWindow(), "onMinimise").removeListener(handler); }
ajax.windows.WinForm.prototype.remove_maximise = function(handler) { this.getEvent(this.getWindow(), "onMaximise").removeListener(handler); }
ajax.windows.WinForm.prototype.remove_restore = function(handler) { this.getEvent(this.getWindow(), "onRestore").removeListener(handler); }

//-----------------------------------------------------------------------------
// Specifies the parent Winform to use as an MDI container.
ajax.windows.WinForm.prototype.setParentWinForm = function(parentWinForm)
{
    this.parentWinForm = parentWinForm;    
    if (this.layer)
    {
        this.setMdiTitle();
        this.addHandlers();
    }
}

//-----------------------------------------------------------------------------
ajax.windows.WinForm.prototype.addMdiChild = function(childWinForm)
{
    // if we are an MDIParent then no scrolling our content!
    this.content.style.overflow = "hidden";
    
    // Set us as the parent of this child
    if (childWinForm)
    {
        childWinForm.setParentWinForm(this); 
        
        // If the child is already loaded, append it to our content
        if (childWinForm.layer)        
            this.content.appendChild(childWinForm.layer);
        
    }
}

//-----------------------------------------------------------------------------
ajax.windows.WinForm.prototype.minimise = function(e, sourceObject)
{
    this.minimised = true;	    
    var flags = ajax.windows.WinFormDisplayFlags;
    
    // Save Settings if we are not maximised, otherwise, say we're not maximised    
    if (!this.maximised)
        this.restoreSettings = {parentNodeStyleOverflow: this.parentNode.style.overflow, titleFloat: this.title.style.cssFloat | this.title.style.styleFloat, x: this.getPosition().x, y: this.getPosition().y, width: this.width, height: this.height, displayFlags: this.displayFlags}; 
               	    	
    // Change the handler of the maximise button...
    ajax.lang.getEvent(this.window, this.maximiseButton, "onclick").removeListener(this.onMaximiseHandler);
    ajax.lang.getEvent(this.window, this.maximiseButton, "onclick").addListener(this.onRestoreHandler);
    ajax.lang.getEvent(this.window, this.title, "ondblclick").removeListener(this.onMaximiseHandler); 
    ajax.lang.getEvent(this.window, this.title, "ondblclick").addListener(this.onRestoreHandler); 
    
    if (this.parentWinForm) // MDI Child
        // Remove the listener to the parent's on Resize event
        this.parentWinForm.getEvent(this.parentWinForm.window, "onResize").removeListener(this.setSizeToContainerHandler);
    else
        // Remove any listener to the window, so when IT resizes, we do also
        ajax.lang.getEvent(this.window, window, "onresize").removeListener(this.setSizeToContainerHandler); 	  
        
    
    // Turn off the minimise button, turn off chrome (to avoid artifacts when we shrink)
    //  and change the handler for maximise to restore
    this.displayFlags |= flags.NoMinimise | flags.NoChrome | flags.NoStatus;
    this.processDisplayFlags();	       
    this.setSize(this.minWidth, this.minHeight);      
    this.setSize(this.minWidth, this.minHeight);          
    this.hide();
    
    
    // Now, what to do... how about pop the title somewhere.
    this.title.style.cssFloat = this.title.style.styleFloat = "left";
    var minimiseTo = this.taskBar || this.parentNode;
    minimiseTo.appendChild(this.title);
    
    // Fire onMinimise
    this.onMinimise.call(this, this.taskBar || this.parentNode);
}

//-----------------------------------------------------------------------------
ajax.windows.WinForm.prototype.maximise = function(e, sourceObject)
{
    this.bringToFront(); // Always to front, regardless
    
    if (this.maximised)
        return;
        
    // Stop here if current flags do not allow maximise!!!
    var displayFlags = ajax.windows.WinFormDisplayFlags;
    if( (this.displayFlags & displayFlags.NoMaximise) == displayFlags.NoMaximise)
        return;	    	    
    
    this.maximised = true;	    
    // Swap the handlers to restore instead of maximise.
    ajax.lang.getEvent(this.window, this.maximiseButton, "onclick").removeListener(this.onMaximiseHandler);
    ajax.lang.getEvent(this.window, this.maximiseButton, "onclick").addListener(this.onRestoreHandler);
    ajax.lang.getEvent(this.window, this.title, "ondblclick").removeListener(this.onMaximiseHandler); 
    ajax.lang.getEvent(this.window, this.title, "ondblclick").addListener(this.onRestoreHandler);  
    
    if (this.parentWinForm) // MDI Child    
        // Add a listener to the parent onResize event, so when IT resizes, we do also
        this.parentWinForm.getEvent(this.parentWinForm.window, "onResize").addListener(this.setSizeToContainerHandler);    
    else
        // add a listener to the window, so when IT resizes, we do also    
        ajax.lang.getEvent(this.window, window, "onresize").addListener(this.setSizeToContainerHandler);	      
        
    
    
    // User has hit the Maximise button so Save current Settings
    this.restoreSettings = {parentNodeStyleOverflow: this.parentNode.style.overflow, titleFloat: this.title.style.cssFloat | this.title.style.styleFloat, x: this.getPosition().x, y: this.getPosition().y, width: this.width, height: this.height, displayFlags: this.displayFlags}; 
    
    
    // Turn off chrome, size up the window, set to 0, 0
    var flags = ajax.windows.WinFormDisplayFlags;
    this.displayFlags |= flags.NoChrome | flags.NoResize | flags.NoDrag;
    this.setPosition(0, 0);
    this.processDisplayFlags();
    
    // Size the window to fit it's container.    
    this.setSizeToContainer();        
    
    // Fire onMaximise
    this.onMaximise.call(this, this.getRect());
}

//-----------------------------------------------------------------------------
ajax.windows.WinForm.prototype.restore = function(e, sourceObject)
{    
    // Change the handler to be Maximise
    ajax.lang.getEvent(this.window, this.maximiseButton, "onclick").removeListener(this.onRestoreHandler);
    ajax.lang.getEvent(this.window, this.maximiseButton, "onclick").addListener(this.onMaximiseHandler);
    ajax.lang.getEvent(this.window, this.title, "ondblclick").removeListener(this.onRestoreHandler);
    ajax.lang.getEvent(this.window, this.title, "ondblclick").addListener(this.onMaximiseHandler);
    // And minimise
    ajax.lang.getEvent(this.window, this.minimiseButton, "onclick").removeListener(this.onRestoreHandler);
    ajax.lang.getEvent(this.window, this.minimiseButton, "onclick").addListener(this.onMinimiseHandler);
    
    if (this.parentWinForm) // MDI Child
        // Remove any listener to the parent, so it resizes without affecting us
        this.parentWinForm.getEvent(this.parentWinForm.window, "onResize").removeListener(this.setSizeToContainerHandler);
    else
        // Remove any listener to the window, so when IT resizes, we do also
        ajax.lang.getEvent(this.window, window, "onresize").removeListener(this.setSizeToContainerHandler); 	    
    
    
    // incase this is coming in from a minimise, put the title back before canvas
    // In theory, just inserting the title in front of the canvas should have worked but this is a workaround for ie6 & FF.
    if (this.parentWinForm)
        this.layer.insertBefore(this.mdiTitle, this.canvas);
    else
        this.layer.insertBefore(this.title, this.mdiTitle);
        
    
    // User wants to restore window to previous state, use restoreSettings object
    var restore = this.restoreSettings;
    this.parentNode.style.overflow  = restore.parentNodeStyleOverflow;
    this.displayFlags               = restore.displayFlags;
    this.processDisplayFlags();	     
    this.setSize(restore.width, restore.height);
    this.title.style.cssFloat       = this.title.style.styleFloat = "";
    
    this.maximised = this.minimised = false;	
        
    this.show(restore.x, restore.y);    
    
    //May not be on top so...
    this.bringToFront();        
    
    // Fire onRestore
    this.onRestore.call(this, this.getRect());	
}


//-----------------------------------------------------------------------------
ajax.windows.WinForm.prototype.showMaximised = function(w, h)
{
    this.show(w, h);
    this.maximise();
}
//-----------------------------------------------------------------------------
ajax.windows.WinForm.prototype.showMinimised = function(w, h)
{
    this.show(w, h);
    this.minimise();
}



//-----------------------------------------------------------------------------
ajax.windows.WinForm.prototype.getText = function()
{
    return this.text;
}

//-----------------------------------------------------------------------------
ajax.windows.WinForm.prototype.setText = function(val)
{
    // Add a space because of the shadow offset.
    this.text = val;
    this.titleShadow.innerHTML = this.text;    
    this.titleText.innerHTML = this.text;
    this.title.title = this.text;
}

//-----------------------------------------------------------------------------
ajax.windows.WinForm.prototype.getStatusText = function(){ return this.statusText.innerHTML; }

//-----------------------------------------------------------------------------
ajax.windows.WinForm.prototype.setStatusText = function(val)
{
    //this.statusText.innerHTML = "&nbsp;" + val;
    this.setStatus("&nbsp;" + val);
}

//-----------------------------------------------------------------------------
ajax.windows.WinForm.prototype.getMenuBar = function()
{///<returns type="ajax.components.MenuBar"/>
    // Only create if it does not exist and we are loaded.
    if (!this.menuBar && this.layer)
    {
        this.menuBar = ajax.lang.safeNew("ajax.components.MenuBar", this.doc, this, this.menuContainer);        
        this.menuBar.show();
        this.menuContainer.style.display = "";
        // Adjust our size to suit
        this.setSize(this.width, this.height);
    }
    return this.menuBar;    
}

//-----------------------------------------------------------------------------
ajax.windows.WinForm.prototype.load = function()
{
	// Create this now, in its hidden state
	this.create();		

    // Create drag Controllers for the WinForm and the Resizer
    this.dragController         = ajax.lang.safeNew("ajax.components.DragController", this.doc, this.title, this.layer);
	this.resizeDragController   = ajax.lang.safeNew("ajax.components.DragController", this.doc, this.resizeButton);
	
	this.addHandlers();
	this.processDisplayFlags();
	this.setSize(this.width, this.height); 
	this.setModal(this.modal);	
	this.setStatusText("Loaded.");
	
	// Autoload template?		
	if (this.get_isTemplateControl())
	    this.loadAutoTemplate(this.getContent());
	
	// Fire onLoad event
	this.onLoad.call(this);
}



//-----------------------------------------------------------------------------
// Override dispose
ajax.windows.WinForm.prototype.dispose = function()
{

    // Get rid of any listeners we have to the window or MDI Parent
    if (this.parentWinForm) // MDI Child
        // Remove the listener to the parent's on Resize event
        this.parentWinForm.getEvent(this.parentWinForm.window, "onResize").removeListener(this.setSizeToContainerHandler);    
    else
        // Remove any listener to the window, so when IT resizes, we do also
        ajax.lang.getEvent(this.window, window, "onresize").removeListener(this.setSizeToContainerHandler); 	
        
    
    // Restore the parentNode if needed.
    if (this.restoreSettings)
	    this.parentNode.style.overflow = this.restoreSettings.parentNodeStyleOverflow;
	
	// specifically delete the title as it can be moved outside the layer (when minimised)
	if (this.title.outerHTML)
		this.title.outerHTML = ""; // ie
	else	    
    	this.title.parentNode.removeChild(this.title); // w3c
    	
    this.removeNode(this.topLayer);
    this.topLayer = null;
    this.layer = null;	
    
    // And Call the default dispose
    ajax.windows.WinForm.superClass.dispose.call(this);    
}

//-----------------------------------------------------------------------------
ajax.windows.WinForm.prototype.addHandlers = function()
{
    // Add The Drag...
    var self = this;
    
    // Add event listeners for the control box
    var arrBoxes = [this.minimiseButton, this.maximiseButton, this.closeButton];
    for (var i = 0; i < arrBoxes.length; i++)
    {
        var mouseOverRouter     = ajax.lang.getEvent(this.window, arrBoxes[i], "onmouseover");
        var mouseDownRouter     = ajax.lang.getEvent(this.window, arrBoxes[i], "onmousedown");
        var mouseOutRouter      = ajax.lang.getEvent(this.window, arrBoxes[i], "onmouseout");
        var mouseUpRouter       = ajax.lang.getEvent(this.window, arrBoxes[i], "onmouseup");               
        
        mouseOverRouter.addListener(this.controlBoxMouseOverHandler);
        mouseDownRouter.addListener(this.controlBoxMouseDownHandler);
        mouseOutRouter.addListener(this.controlBoxMouseOutHandler);
        mouseUpRouter.addListener(this.controlBoxMouseOverHandler);        
    }
    
    // Min/Max/Close 
    ajax.lang.getEvent(this.window, this.closeButton, "onclick").addListener(this.onCloseButtonHandler);
    ajax.lang.getEvent(this.window, this.maximiseButton, "onclick").addListener(this.onMaximiseHandler);
    ajax.lang.getEvent(this.window, this.minimiseButton, "onclick").addListener(this.onMinimiseHandler);   
    ajax.lang.getEvent(this.window, this.title, "ondblclick").addListener(this.onMaximiseHandler);           
    
    // We do not want the user to "select" from the text on a winform
   ajax.lang.getEvent(this.window, this.layer, "onselectstart").addListener(this.noSelectHandler);
    
    
    // When the user clicks on the winForm, bring it to front (if not already)
    //ajax.lang.getEvent(this.window, this.layer, "onclick").addListener(function(){setTimeout(self.bringToFront, self.focusTimeout)});
    ajax.lang.getEvent(this.window, this.layer, "onclick").addListener(function(){self.bringToFront()});
    
    // We want to know when the resizeDragController drags
    this.resizeDragController.getEvent(this.window, "onDragStart").addListener(this.onResizeStart);
    this.resizeDragController.getEvent(this.window, "onDrag").addListener(this.onResizeHandler);
    this.resizeDragController.getEvent(this.window, "onDragEnd").addListener(this.onResizeEnd); 
    
    // We want to know about the window has been moved, so we can update our settings and fire our "onMove" event
    this.dragController.getEvent(this.window, "onDragEnd").addListener(function(e)
        {             
            self.setPosition(e.x, e.y);            
        }
    );     
    
    // Call base
    ajax.windows.WinForm.superClass.addHandlers.call(this);         
}

//-----------------------------------------------------------------------------
ajax.windows.WinForm.prototype.processDisplayFlags = function(newFlags)
{///<param name="newFlags" type="ajax.windows.WinFormDisplayFlags"/>
    
    // Get flags
    this.displayFlags = ajax.isDefined(newFlags) ? newFlags : this.displayFlags;
    var displayFlags = ajax.windows.WinFormDisplayFlags;
    
    // NoTitle
    if ( (this.displayFlags & displayFlags.NoTitle) == displayFlags.NoTitle)
        this.title.style.visibility = "hidden";
    else
        this.title.style.visibility = "";        

    // NoChrome               
    // Prcessed below
    // NoStatus
    if ( (this.displayFlags & displayFlags.NoStatus) == displayFlags.NoStatus)
        this.status.style.visibility = "hidden";
    else    
        this.status.style.visibility = "";        
            
    // NoResize
    if ( (this.displayFlags & displayFlags.NoResize) == displayFlags.NoResize)
        this.resizeButton.style.visibility = "hidden";
    else
        this.resizeButton.style.visibility = "";        
    // NoMinimise - We force this if the window is modal
    if ( (this.displayFlags & displayFlags.NoMinimise) == displayFlags.NoMinimise || this.modal)
        this.minimiseButton.style.visibility = "hidden";
    else
        this.minimiseButton.style.visibility = "";        
    //NoMaximise
    if ( (this.displayFlags & displayFlags.NoMaximise) == displayFlags.NoMaximise)
        this.maximiseButton.style.visibility = "hidden";
    else
        this.maximiseButton.style.visibility = "";


    // NoClose
    if ( (this.displayFlags & displayFlags.NoClose) == displayFlags.NoClose)
        this.closeButton.style.visibility = "hidden";
    else
        this.closeButton.style.visibility = "";
    // NoDrag
    if ( (this.displayFlags & displayFlags.NoDrag) == displayFlags.NoDrag)
        this.dragController.removeHandler();
    else
        this.dragController.addHandler();
          
}


//-----------------------------------------------------------------------------
// To help encapsulate this implementation, clients may need to know the actual pixel 
// dimensions of certain WinForm elements - starting with the content layer
ajax.windows.WinForm.prototype.getContentRect = function()
{
    ///<returns type="ajax.geometry.shapes.Rectangle"/>
    return ajax.lang.safeNew("ajax.geometry.shapes.Rectangle", 
        0, 0,
        parseInt(this.innerCanvas.style.width), parseInt(this.content.style.height));
}

//-----------------------------------------------------------------------------
ajax.windows.WinForm.prototype.setSize = function(width, height)
{   
    // Final validation
    width   = Math.max(width, this.minWidth);
    height  = Math.max(height, this.minHeight); 
    
    
    // Re-Calculate min height as we go
    this.minHeight = 0;        
          
    
    // Get flags
    var displayFlags = ajax.windows.WinFormDisplayFlags;

    // Calculate the new sizes for all elements that need it...
    var canvasHeight        = height;
    var canvasTop           = 0;    
    var innerCanvasHeight   = height;
    var innerCanvasWidth    = width;
    var contentHeight       = 0;     
    
    
    // If the title is showing then the canvas will have less height 
    if (this.title.style.visibility != "hidden")
    {
        // We have Title!
        canvasTop           += parseInt(this.title.style.height);
        
        canvasHeight        -= parseInt(this.title.style.height);
        innerCanvasHeight   -= parseInt(this.title.style.height);    
        this.minHeight      += parseInt(this.title.style.height);           
    }
    else
    {    
        this.innerCanvas.style.top = "2px";
    }
    
    // If there is NoChrome then we have More width
    if ( (this.displayFlags & displayFlags.NoChrome) == displayFlags.NoChrome)
    {
        this.innerCanvas.style.left = "0px";
        this.innerCanvas.style.top = "0px";         
    }        
    else
    {                
        this.minHeight += 4;
        
        if (this.title.style.visibility != "hidden")
        {
            this.innerCanvas.style.top  = "0px";
            innerCanvasHeight += 2;
        }
        else        
            this.innerCanvas.style.top = "2px";
                                  
        this.innerCanvas.style.left = "2px";       
        
        innerCanvasHeight -= 4;
        innerCanvasWidth  -= 4;                
    }
    
    // At this point the content height is the same as the innerCanvas, unless there is a status bar...
    contentHeight       = innerCanvasHeight;
    
    
    // If we have a status bar then we have less height
    if (this.status.style.visibility != "hidden")
    {
        contentHeight  -= parseInt(this.status.style.height)+1; //parseInt(this.status.style.borderTopWidth));        
        this.minHeight += parseInt(this.status.style.height)+1; // Status Border
    }
    // if we have a menu bar then we have less height
    if (this.menuBar)
    {
        contentHeight -= this.menuBar.getRect().height;     
        this.minHeight += this.menuBar.getRect().height;   
    }        
    
        
    // if the content height < 0 (NOT ALLOWED) then do not allow
    contentHeight = Math.max(0, contentHeight);
        
    // Now set the heights on the actual elements    
    this.layer.style.width          = width + "px";
    this.layer.style.height         = height + "px";
    this.title.style.width          = width + "px";
    this.canvas.style.top           = canvasTop + "px";
    this.canvas.style.height        = canvasHeight + "px";
    //this.canvas.style.width         = innerCanvasWidth + "px";
    this.innerCanvas.style.width    = innerCanvasWidth + "px";
    this.innerCanvas.style.height   = innerCanvasHeight + "px";
    this.content.style.height       = contentHeight + "px";  
    // And for the modal layer 
    this.modalLayer.style.height    = this.doc.documentElement.scrollHeight + "px"; 
		
	
	// If the size has changed then store the new values and fire the onResize event
    if (width != this.width || height != this.height)
    {        
        this.width  = width;
        this.height = height;
        // Fire our onResize event...
	    this.onResize.call(this, this.getRect());
    }
	  
}

//-----------------------------------------------------------------------------
ajax.windows.WinForm.prototype.getModal = function() { return this.modal };

//-----------------------------------------------------------------------------
ajax.windows.WinForm.prototype.setModal = function(val)
{
    this.modal = val;
    
    // setModal
        
    if (this.modal)
    {
        this.layer.id       = "";
        this.modalLayer.id  = this.layerName;
        this.modalLayer.appendChild(this.transBack);
        this.modalLayer.appendChild(this.layer);        
        this.parentNode.appendChild(this.modalLayer);          
        this.topLayer = this.modalLayer;                                             
    }
    else    
    {
        this.modalLayer.id  = "";
        this.layer.id       = this.layerName;
        this.parentNode.appendChild(this.layer);
        this.topLayer = this.layer;
    }   
    
    this.topLayer.parentObject = this;
}

//-----------------------------------------------------------------------------
ajax.windows.WinForm.prototype.create = function()
{
    if (!this.windowTemplateHtml)
        ajax.debug.Output.writeLn("No windowTemplate for WinForm");
        
        
    ajax.lang.safeDestroy(this.doc.getElementById(this.layerName));
                      
    // Load from Html
    var self                        = this;
    
    // Get flags
    var displayFlags = ajax.windows.WinFormDisplayFlags;
    
    //create temp Loading Layer at document body level    
    var loadingDiv = this.loadContentToDiv(this.windowTemplateHtml);    
    
    this.layer          = this.doc.getElementById("TEMPLATE_layer");
    if (this.modal)
        this.layer.id   = "";
    else
        this.layer.id   = this.layerName;
    
    this.layer.setAttribute("name", this.layerName);    
    this.copyProperties(this.layer.style, this.layerStyle);
    
    this.frame          = this.doc.getElementById("TEMPLATE_frame");
    this.frame.id       = "";
    
    // Title
    this.title          = this.doc.getElementById("TEMPLATE_title");
    this.title.id       = "";
    this.icon           = this.doc.getElementById("TEMPLATE_icon");
    this.icon.src       = this.iconFile;
    this.icon.id = "";
    this.titleShadow    = this.doc.getElementById("TEMPLATE_titleShadow");
    this.titleShadow.id = "";    
    this.titleText      = this.doc.getElementById("TEMPLATE_titleText");
    this.titleText.id   = "";    
    
    
    // Create a blank image to pop in the control box buttons
    var blankImage = this.doc.createElement("img");
    blankImage.src = this.blankImageFile;
    blankImage.style.width = blankImage.style.height = "14px";    
    
    this.minimiseButton = this.doc.getElementById("TEMPLATE_minimise");
    this.minimiseButton.id = "";
    
    //this.minimiseButton.appendChild(blankImage);
    
    this.maximiseButton = this.doc.getElementById("TEMPLATE_maximise");
    this.maximiseButton.id = "";
        
    this.closeButton = this.doc.getElementById("TEMPLATE_close");
    this.closeButton.id = "";    
    
    this.resizeButton   = this.doc.getElementById("TEMPLATE_resize");
    this.resizeButton.id = "";
    this.resizeButton.src = this.resizeFile;
    
    var tLeft           = this.doc.getElementById("TEMPLATE_titleLeft");
    tLeft.id            = "";
    tLeft.style.background = "url(" + this.titleLeftImage + ") left top no-repeat";
    var tMid            = this.doc.getElementById("TEMPLATE_titleMiddle");
    tMid.id             = "";
    tMid.style.background = "url(" + this.titleMiddleImage + ")";
    var tRight          = this.doc.getElementById("TEMPLATE_titleRight");
    tRight.id           = "";
    tRight.style.background = "url(" + this.titleRightImage + ") left top no-repeat";
    
    // Top references (always valid - unlike this.title can swap)
    this.topTitle           = this.title;
    this.topTitleText       = this.titleText;
    this.topMinimiseButton  = this.minimiseButton;
    this.topMaximiseButton  = this.maximiseButton;
    this.topCloseButton     = this.closeButton;
    
    // MDI Title ####    
    this.mdiTitle               = $(this.doc, "TEMPLATE_mdiTitle");
    this.mdiTitle.id            = "";    
    this.mdiTitleText           = $(this.doc, "TEMPLATE_mdiTitleText");
    this.mdiTitleText.id        = "";
    this.mdiMinimiseButton      = $(this.doc, "TEMPLATE_mdiMinimise");
    this.mdiMinimiseButton.id   = "";
    this.mdiMaximiseButton      = $(this.doc, "TEMPLATE_mdiMaximise");
    this.mdiMaximiseButton.id   = "";
    this.mdiCloseButton         = $(this.doc, "TEMPLATE_mdiClose");
    this.mdiCloseButton.id      = "";
    
    this.mdiTitle.style.background = "url(" + this.mdiTitleBackground + ")";    
    this.setMdiTitle();                
    
    this.menuContainer  = this.doc.getElementById("TEMPLATE_menuContainer");
    this.menuContainer.id = "";
    
    this.canvas         = this.doc.getElementById("TEMPLATE_canvas");
    this.canvas.id      = "";
    this.copyProperties(this.canvas.style, this.canvasStyle);
    this.innerCanvas    = this.doc.getElementById("TEMPLATE_innerCanvas");
    this.innerCanvas.id = "";
    this.copyProperties(this.innerCanvas.style, this.innerCanvasStyle);
    this.content        = this.doc.getElementById("TEMPLATE_content"); 
    this.content.id     = "";
    this.copyProperties(this.content.style, this.contentStyle);
    this.status         = this.doc.getElementById("TEMPLATE_status");
    this.status.id      = "";
    this.copyProperties(this.status.style, this.statusStyle);
    this.statusText     = this.doc.getElementById("TEMPLATE_statusText");
    this.statusText.id  = "";
    
            

     // Destroy the loadingDIv - with our ammended winForm in it!!
     //this.removeNode(loadingDiv);
     
     loadingDiv.parentNode.removeChild(loadingDiv);
    
    
    // Create Modal Layers
    this.modalLayer                 = this.doc.createElement("div");
    this.modalLayer.id              = "";
    this.copyProperties(this.modalLayer.style, this.modalLayerStyle);            
    this.transBack                  = this.doc.createElement("div");
    this.copyProperties(this.transBack.style, this.transBackStyle);
    // Due to an IE problem with Form Fields (showing through) we need an IFRAME for IE.
    this.backFrame                  = this.doc.createElement("iframe");
    this.backFrame.src = ajax.getDomainPath() + "/images/BlackPage.html"; 
    this.copyProperties(this.backFrame, this.hiddenFrameStyling);
    //
    if (this.doc.all)
        this.transBack.appendChild(this.backFrame);
       
    
    // If not ie, make the position "fixed" instead
    if (!this.doc.all)         
        this.transBack.style.position = "fixed";                	
	return true;
};

//-----------------------------------------------------------------------------
ajax.windows.WinForm.prototype.setMdiTitle = function()
{
    if (this.parentWinForm) // MDI Child  
    {
        //this.removeNode(this.title);
        // Note: Using all 3 methods to keep the node but have it not display!! (ie6 & FF)
        this.title.style.height         = "0px";
        this.title.style.visibility     = "hidden";
        this.title.style.display        = "none";
        
        this.mdiTitle.style.height      = "23px";      
        this.mdiTitle.style.visibility  = "visible";   
        this.mdiTitle.style.display     = "block";                     
                
        this.title          = this.mdiTitle; 
        this.titleText      = this.mdiTitleText;
        this.titleShadow    = this.mdiTitleText;
        
        this.minimiseButton = this.mdiMinimiseButton;
        this.maximiseButton = this.mdiMaximiseButton;
        this.closeButton    = this.mdiCloseButton;                
    }    
    else
    {
        //this.removeNode(this.mdiTitle);
        this.mdiTitle.style.height      = "0px";
        this.mdiTitle.style.visibility  = "hidden";
        this.mdiTitle.style.display     = "none";
        this.title.style.height         = "23px";     
        this.title.style.visibility     = "visible";   
        this.title.style.display        = "block";
        
        this.title              = this.topTitle;
        this.titleText          = this.topTitleText;
        this.minimiseButton     = this.topMinimiseButton;
        this.maximiseButton     = this.topMaximiseButton;
        this.closeButton        = this.topCloseButton;
        
    }
    // ####
    
    this.setText(this.text); // always set text like this.
    this.title.style.visibility = "visible";
    this.copyProperties(this.title.style, this.titleStyle);
    this.copyProperties(this.minimiseButton.style, this.minimiseButtonStyle);
    this.copyProperties(this.maximiseButton.style, this.maximiseButtonStyle);
    this.copyProperties(this.closeButton.style, this.closeButtonStyle);
    
    // If this form is loaded and already has a dragController...
    if (this.dragController)
        this.dragController.setSourceElement(this.title);
}

//-----------------------------------------------------------------------------
ajax.windows.WinForm.prototype.show = function(x, y, parentEle, e)
{
    // If not loaded then load
    if (!this.layer)
        this.load();
    // If minimised then restore in order to show
    if (this.minimised)
        this.restore();
        
    this.setPosition(x, y, parentEle, e);
         
    if (this.modal)    
    {                             
        var ele = this.doc.documentElement;
        var w = ele.offsetWidth;
        var p = ele.clientWidth;        
        this.topLayer.style.width = ele.scrollWidth + "px";
        this.topLayer.style.height = ele.scrollHeight + "px";
        this.backFrame.style.width =   this.topLayer.style.width;
        this.backFrame.style.height =   this.topLayer.style.height;           
    }
             
    
    
	    
    if (this.menuBar)
        this.menuBar.show();

    // Only show if not visible.
    if (!this.visible)
    {
        // actually showing the WinForm
        this.topLayer.style.visibility = "visible";
        this.layer.style.visibility = "visible";
	    // fire onShow event
	    this.visible = true;
	    this.onShow.call(this, this.getRect());
	}
	
	return false;
	
};

//-----------------------------------------------------------------------------
ajax.windows.WinForm.prototype.hide = function()
{				
    this.topLayer.style.visibility  = "hidden";
    if (this.menuBar)
        this.menuBar.hide();
            
	ajax.windows.WinForm.superClass.hide.call(this);	
};


//-----------------------------------------------------------------------------
ajax.windows.WinForm.prototype.getStatus = function()
{
    return this.statusText.innerHTML;
}

//-----------------------------------------------------------------------------
ajax.windows.WinForm.prototype.setStatus = function(val)
{
    this.statusText.innerHTML = val;
}

//-----------------------------------------------------------------------------
ajax.windows.WinForm.prototype.toString = function()
{
    return "ajax.windows.WinForm";
}

//-----------------------------------------------------------------------------
ajax.windows.WinForm.prototype.toClassName = function()
{
    return ajax.lang.getClassName("ajax.windows.WinForm");
}

//-----------------------------------------------------------------------------

ajax.windows.WinForm.prototype.getContent = function()
{///<returns domElement="true" mayBeNull="true" type="domElement">dom element</returns>
    return this.content
}

// Statics
//-----------------------------------------------------------------------------
ajax.windows.WinForm.cast = function(obj)
{///<returns type="ajax.windows.WinForm" />
    return obj;
}
